# -*- coding: utf-8 -*-
import datetime
import json

import requests
import yaml
from dateutil.parser import parse
from requests.exceptions import RequestException

PRIVATE_TOKEN = "XXXXXXXXX"
API_PATH = "http://gitlab.example.com/api/v3/"
ALL_PROJECT_API = "".join([API_PATH, "projects?simple=ture&search={}"])
SEARCH_API = "".join([API_PATH, "projects?search={}"])
COMMITS_API = "".join([API_PATH, "projects/{}/repository/commits?ref_name=master&since={}"])
SINGLE_COMMIT_API = "".join([API_PATH, "projects/{}/repository/commits/{}"])

project_map = {}


def search_project(name=None):
    try:
        if name:
            return get_projects()[name]
    except KeyError:
        return None


def get_projects():
    if len(project_map) != 0:
        return project_map

    pconf = yaml.load(open('project.yml'))
    for p in pconf['projects']:
        page = 1
        url = ALL_PROJECT_API.format(str(p).split('/')[1])
        while True:
            url = url + "&page=" + str(page)
            r = requests.get(url, headers={"PRIVATE-TOKEN": PRIVATE_TOKEN}, stream=True, verify=False)
            p_json_arr = json.loads(r.text)
            if len(p_json_arr) == 0:
                break
            for elem in p_json_arr:
                project_map[elem['path_with_namespace']] = elem

            page += 1
    return project_map


def get_commits(path_with_namespace):
    try:
        all_commits = []
        page = 1
        p = get_projects()[path_with_namespace]
        d31 = datetime.datetime.now().date() - datetime.timedelta(days=31)
        url = COMMITS_API.format(p['id'], d31.strftime('%Y-%m-%dT%H:%M:%S.%fZ'))
        while True:
            url = url + "&page=" + str(page)
            r = requests.post(url, headers={"PRIVATE-TOKEN": PRIVATE_TOKEN}, stream=True, verify=False)
            cp = json.loads(r.text)
            if len(cp) == 0:
                break
            all_commits.extend(cp)
            page += 1
        return all_commits
    except RequestException:
        return []


def get_single_commit(pid, sha):
    try:
        url = SINGLE_COMMIT_API.format(pid, sha)
        r = requests.post(url, headers={"PRIVATE-TOKEN": PRIVATE_TOKEN}, stream=True, verify=False)
        return json.loads(r.text)
    except RequestException:
        return None


def getDayp(stime):
    cdatetime = parse(stime)
    z = datetime.datetime.now().date() - cdatetime.date()
    return (31 - z.days) * 10 + cdatetime.hour * 10 / 24


def get_commits_json():
    pconf = yaml.load(open('project.yml'))
    commits_json = []
    for p in pconf['projects']:
        obj = {}
        max_change = 0
        obj['project'] = p
        commits = []
        p_all_commits = get_commits(p)
        for commit in p_all_commits:
            cmt = get_single_commit(get_projects()[p]['id'], commit['id'])
            if cmt:
                if max_change < cmt['stats']['total']:
                    max_change = cmt['stats']['total']
                # cobj = collections.OrderedDict
                cobj = [getDayp(cmt['committed_date']), cmt['stats']['total'], cmt['author_name'], cmt['short_id'],
                        parse(cmt['committed_date']).strftime('%Y-%m-%d %H:%M:%S')]
                commits.append(cobj)
        obj['commits'] = commits
        obj['max_change'] = max_change
        commits_json.append(obj)

    return sorted(commits_json,key=lambda dict: dict['project'])


def save(filename, contents):
    fh = open(filename, 'w')
    fh.write(contents)
    fh.close()


if __name__ == '__main__':
    save('commits.json',json.dumps(get_commits_json(), encoding="UTF-8", separators=(',', ':')))
